/*!
 * \file ExecuteDefs.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 执行单元定义文件
 * \details 定义了执行单元系统的基础类和接口，包括执行上下文、执行单元基类和执行工厂接口
 */
#pragma once
#include "../Includes/WTSDataDef.hpp"
#include "../Includes/WTSCollection.hpp"

NS_WTP_BEGIN
class WTSTickData;
class WTSHisTickData;
class WTSVariant;
class WTSCommodityInfo;
class WTSSessionInfo;

/// @brief 订单ID集合类型定义
typedef std::vector<uint32_t> OrderIDs;
/// @brief 订单映射类型定义
typedef WTSMap<uint32_t> OrderMap;

//////////////////////////////////////////////////////////////////////////
/**
 * @class ExecuteContext
 * @brief 执行上下文类
 * @details 执行单元的运行环境和接口提供者，负责为执行单元提供市场数据、交易接口和其他必要服务。
 *          主要功能包括：
 *          - 市场数据查询和获取
 *          - 持仓信息管理
 *          - 订单管理和查询
 *          - 交易接口提供
 *          - 基础数据服务
 *          - 定时器注册
 *          
 *          执行上下文是执行单元与系统之间的桥梁，封装了所有必要的
 *          系统服务，使执行单元能够专注于具体的执行逻辑实现。
 */
class ExecuteContext
{
public:
	ExecuteContext(){}
	virtual ~ExecuteContext(){}

public:
	/**
	 * @brief 获取tick数据
	 * @details 获取指定合约的历史tick数据，用于技术分析和策略决策。
	 * @param stdCode 标准合约代码
	 * @param count 数据条数
	 * @param etime 结束时间，0表示当前时间
	 * @return WTSTickSlice* 历史数据封装器指针
	 */
	virtual WTSTickSlice*	getTicks(const char* stdCode, uint32_t count, uint64_t etime = 0) = 0;

	/**
	 * @brief 获取最新的Tick数据
	 * @details 获取指定合约的最新tick数据，包含最新的价格和成交信息。
	 * @param stdCode 标准合约代码
	 * @return WTSTickData* tick数据指针
	 */
	virtual WTSTickData*	grabLastTick(const char* stdCode) = 0;

	/**
	 * @brief 获取持仓
	 * @details 获取指定合约的当前持仓信息，支持净持仓和分方向持仓查询。
	 * @param stdCode 标准合约代码
	 * @param validOnly 只获取有效持仓
	 * @param flag 持仓类型：1-多头，2-空头，3-净持仓
	 * @return double 净持仓的数量：多头>0，空头<0
	 */
	virtual double getPosition(const char* stdCode, bool validOnly = true, int32_t flag = 3) = 0;

	/**
	 * @brief 获取未完成订单
	 * @details 获取指定合约的所有未完成订单信息。
	 * @param stdCode 标准合约代码
	 * @return OrderMap* 本地订单ID-WTSOrderInfo的映射
	 */
	virtual OrderMap* getOrders(const char* stdCode) = 0;

	/**
	 * @brief 获取未成交数量
	 * @details 获取指定合约在开平仓后的未成交数量。
	 * @param stdCode 标准合约代码
	 * @return double 未成交数量
	 */
	virtual double getUndoneQty(const char* stdCode) = 0;

	/**
	 * @brief 买入接口
	 * @details 下达买入订单，支持开仓和平仓操作。
	 * @param stdCode 标准合约代码
	 * @param price 委托价格，0为市价单
	 * @param qty 委托数量
	 * @param bForceClose 是否强制平仓
	 * @return OrderIDs 本地订单号集合：一个买入订单可能会拆分成3个子订单
	 */
	virtual OrderIDs buy(const char* stdCode, double price, double qty, bool bForceClose = false) = 0;

	/**
	 * @brief 卖出接口
	 * @details 下达卖出订单，支持开仓和平仓操作。
	 * @param stdCode 标准合约代码
	 * @param price 委托价格，0为市价单
	 * @param qty 委托数量
	 * @param bForceClose 是否强制平仓
	 * @return OrderIDs 本地订单号集合：一个卖出订单可能会拆分成3个子订单
	 */
	virtual OrderIDs sell(const char* stdCode, double price, double qty, bool bForceClose = false) = 0;

	/**
	 * @brief 根据本地订单号撤单
	 * @details 撤销指定的本地订单。
	 * @param localid 本地订单号
	 * @return bool 返回撤单指令是否下达成功
	 */
	virtual bool	cancel(uint32_t localid) = 0;

	/**
	 * @brief 撤销指定方向的所有订单
	 * @details 批量撤销指定合约和方向的订单。
	 * @param stdCode 标准合约代码
	 * @param isBuy 买or卖方向
	 * @param qty 数量限制，如果有多个委托，那么按时间顺序一个一个撤销，直到撤销的数量达到等于qty。
	 *            如果传入0，则表示该方向全部撤单或以内的所有订单
	 * @return OrderIDs 返回实际发送撤单指令的订单集合
	 */
	virtual OrderIDs cancel(const char* stdCode, bool isBuy, double qty = 0) = 0;

	/**
	 * @brief 写日志
	 * @details 写入执行单元的日志信息。
	 * @param message 日志消息
	 */
	virtual void writeLog(const char* message) = 0;

	/**
	 * @brief 获取品种参数
	 * @details 获取指定合约的品种信息，包含交易参数等。
	 * @param stdCode 标准合约代码
	 * @return WTSCommodityInfo* 品种信息指针
	 */
	virtual WTSCommodityInfo* getCommodityInfo(const char* stdCode) = 0;

	/**
	 * @brief 获取交易时段模板信息
	 * @details 获取指定合约的交易时段配置信息。
	 * @param stdCode 标准合约代码
	 * @return WTSSessionInfo* 交易时段信息指针
	 */
	virtual WTSSessionInfo* getSessionInfo(const char* stdCode) = 0;

	/**
	 * @brief 获取当前时间
	 * @details 获取系统当前时间，精确到毫秒。
	 * @return uint64_t 时间戳，格式如20191127174139500
	 */
	virtual uint64_t	getCurTime() = 0;

	/**
	 * @brief 注册定时器
	 * @details 为执行单元注册定时回调。
	 * @param stdCode 标准合约代码
	 * @param elapse 时间间隔，单位毫秒
	 * @return bool 是否注册成功
	 */
	virtual bool		registerTimer(const char* stdCode, uint32_t elapse){ return false; }
};

//////////////////////////////////////////////////////////////////////////
/**
 * @class ExecuteUnit
 * @brief 执行单元基类
 * @details 执行单元的基础类，定义了执行单元的基本接口和生命周期。
 *          主要功能包括：
 *          - 目标持仓设置和管理
 *          - 市场数据处理
 *          - 交易回报处理
 *          - 通道状态管理
 *          
 *          执行单元负责将策略的交易信号转换为具体的交易指令，
 *          并处理订单执行过程中的各种回报和状态变化。
 *          是策略层和交易层之间的桥梁。
 */
class ExecuteUnit
{
public:
	/**
	 * @brief 构造函数
	 */
	ExecuteUnit() :_ctx(NULL), _code(""){}
	virtual ~ExecuteUnit(){}

public:
	/**
	 * @brief 获取执行单元名称
	 * @details 返回执行单元的唯一标识名称。
	 * @return const char* 执行单元名称
	 */
	virtual const char* getName() = 0;

	/**
	 * @brief 获取执行单元工厂名称
	 * @details 返回创建此执行单元的工厂名称。
	 * @return const char* 工厂名称
	 */
	virtual const char* getFactName() = 0;

	/**
	 * @brief 初始化执行单元
	 * @details 执行单元的初始化方法，设置运行环境和配置参数。
	 * @param ctx 执行单元运行环境
	 * @param stdCode 绑定的合约代码
	 * @param cfg 配置参数
	 */
	virtual void init(ExecuteContext* ctx, const char* stdCode, WTSVariant* cfg){ _ctx = ctx; _code = stdCode; }

public:
	/**
	 * @brief 设置新的目标持仓
	 * @details 设置执行单元的目标持仓，执行单元会朝着这个目标进行交易。
	 * @param stdCode 标准合约代码
	 * @param newVol 新的目标持仓量
	 */
	virtual void set_position(const char* stdCode, double newVol) = 0;

	/**
	 * @brief 清空全部持仓
	 * @details 清空所有持仓，包括多头和空头持仓。
	 * @param stdCode 标准合约代码
	 */
	virtual void clear_all_position(const char* stdCode){}

	/**
	 * @brief tick数据回调
	 * @details 处理实时tick数据，用于执行决策和订单管理。
	 * @param newTick 最新的tick数据
	 */
	virtual void on_tick(WTSTickData* newTick) = 0;

	/**
	 * @brief 成交回报
	 * @details 处理订单成交回报，更新持仓和执行状态。
	 * @param localid 本地订单ID
	 * @param stdCode 标准合约代码
	 * @param isBuy 买或卖方向
	 * @param vol 成交数量，如果没有方向，通过isBuy确定是买入还是卖出
	 * @param price 成交价格
	 */
	virtual void on_trade(uint32_t localid, const char* stdCode, bool isBuy, double vol, double price) = 0;

	/**
	 * @brief 订单回报
	 * @details 处理订单状态变化回报，监控订单执行进度。
	 * @param localid 本地订单ID
	 * @param stdCode 标准合约代码
	 * @param isBuy 买或卖方向
	 * @param leftover 剩余数量
	 * @param price 委托价格
	 * @param isCanceled 是否已撤销
	 */
	virtual void on_order(uint32_t localid, const char* stdCode, bool isBuy, double leftover, double price, bool isCanceled) = 0;

	/**
	 * @brief 下单回报
	 * @details 处理下单确认回报，确认订单是否成功提交。
	 * @param localid 本地订单ID
	 * @param stdCode 标准合约代码
	 * @param bSuccess 是否成功
	 * @param message 错误信息
	 */
	virtual void on_entrust(uint32_t localid, const char* stdCode, bool bSuccess, const char* message) = 0;

	/**
	 * @brief 交易通道就绪回调
	 * @details 交易通道连接成功时的回调函数。
	 */
	virtual void on_channel_ready() = 0;

	/**
	 * @brief 交易通道丢失回调
	 * @details 交易通道连接断开时的回调函数。
	 */
	virtual void on_channel_lost() = 0;

protected:
	ExecuteContext*	_ctx;		///< 执行上下文指针
	std::string		_code;		///< 绑定的合约代码
};

//////////////////////////////////////////////////////////////////////////
/// @brief 执行单元枚举回调函数类型
/// @param factName 工厂名称
/// @param unitName 执行单元名称
/// @param isLast 是否为最后一个
typedef void(*FuncEnumUnitCallback)(const char* factName, const char* unitName, bool isLast);

/**
 * @class IExecuterFact
 * @brief 执行单元工厂接口
 * @details 执行单元工厂的核心接口，负责执行单元的创建、删除和管理。
 *          主要功能包括：
 *          - 执行单元实例创建和销毁
 *          - 执行单元类型枚举
 *          - 工厂标识管理
 *          
 *          执行单元工厂采用工厂模式设计，支持动态加载和卸载执行单元模块，
 *          为交易执行系统提供灵活的扩展机制。不同的执行算法可以通过
 *          不同的执行单元来实现，如TWAP、VWAP、冰山算法等。
 */
class IExecuterFact
{
public:
	IExecuterFact(){}
	virtual ~IExecuterFact(){}

public:
	/**
	 * @brief 获取工厂名称
	 * @details 返回执行单元工厂的唯一标识名称。
	 * @return const char* 工厂名称
	 */
	virtual const char* getName() = 0;

	/**
	 * @brief 枚举执行单元
	 * @details 枚举工厂支持的所有执行单元类型，通过回调函数返回信息。
	 * @param cb 枚举回调函数，用于接收执行单元信息
	 */
	virtual void enumExeUnit(FuncEnumUnitCallback cb) = 0;

	/**
	 * @brief 根据名称创建执行单元
	 * @details 根据指定的执行单元名称创建新的执行单元实例。
	 * @param name 执行单元名称
	 * @return ExecuteUnit* 执行单元实例指针，创建失败返回nullptr
	 */
	virtual ExecuteUnit* createExeUnit(const char* name) = 0;

	/**
	 * @brief 删除执行单元
	 * @details 销毁指定的执行单元实例并释放相关资源。
	 * @param unit 要删除的执行单元指针
	 * @return bool true表示删除成功，false表示失败
	 */
	virtual bool deleteExeUnit(ExecuteUnit* unit) = 0;
};

/// @brief 创建执行工厂函数指针类型
typedef IExecuterFact* (*FuncCreateExeFact)();

/// @brief 删除执行工厂函数指针类型
typedef void(*FuncDeleteExeFact)(IExecuterFact* &fact);

NS_WTP_END